package com.ytjj.quartz.service;

import com.ytjj.common.service.RedisService;
import com.ytjj.qmyx.mall.model.Channel;
import com.ytjj.qmyx.mall.model.ChannelStatisticsNew;
import com.ytjj.quartz.dao.ChannelDao;
import com.ytjj.quartz.dao.ChannelStatisticsNewDao;
import com.ytjj.quartz.dao.PlatformStatisticsDao;
import com.ytjj.quartz.model.ChannelUser;
import com.ytjj.quartz.model.DataStatisticsRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.stereotype.Service;
import org.springframework.data.mongodb.core.query.Criteria;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@Slf4j
@RefreshScope
public class ChannelStatisticsService {
    @Resource
    private ChannelStatisticsNewDao channelStatisticsNewDao;
    @Autowired
    private RedisService redisService;
    @Resource
    private ChannelDao channelDao;
    @Resource
    private PlatformStatisticsDao platformStatisticsDao;
    @Resource
    private MongoTemplate mongoTemplate;

    @Value("${copyDataToBhtChannel:}")
    private String copyDataToBhtChannel;

    final String PAGE_STATISTICS = "page_statistics";

    public boolean getPlatformStatisticsList(DataStatisticsRequest dataStatisticsRequest) {
        LocalDateTime startTime = dataStatisticsRequest.getStartTime();
        LocalDateTime endTime = dataStatisticsRequest.getEndTime();
        String platform = dataStatisticsRequest.getPlatform();
        //默认14天
        Integer dayInterval=14;
        if(dataStatisticsRequest.getDayInterval()!=null){
            dayInterval=dataStatisticsRequest.getDayInterval();
        }
        List<Channel> channels = channelDao.getChannelNameList(dayInterval);

        if(channels != null && !channels.isEmpty()) {
            this.getChannelData(startTime, endTime, platform, channels, dataStatisticsRequest, dataStatisticsRequest);
        }
        return true;
    }

    /**
     * 查询渠道数据
     *
     * @param startTime
     * @param endTime
     * @param platform
     * @param channelList
     * @param statisticsRequest
     * @param dataStatisticsRequest
     * @return
     */
    public void getChannelData(LocalDateTime startTime, LocalDateTime endTime, String platform, List<Channel> channelList, DataStatisticsRequest statisticsRequest, DataStatisticsRequest dataStatisticsRequest) {
        List<String> copyDataToBhtChannelList=new ArrayList<>();
        if(StringUtils.isNotBlank(copyDataToBhtChannel)){
            String[] copyDataToBhtS=copyDataToBhtChannel.split(",");
            for(String str:copyDataToBhtS){
                copyDataToBhtChannelList.add(str);
            }
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startTimeStr = "";
        String endTimeStr = "";
        if (null != startTime) {
            startTimeStr = df.format(startTime);
        }
        if (null != endTime) {
            endTimeStr = df.format(endTime);
            statisticsRequest.setSearchDate(endTimeStr);
        }
        //扣量(给的比例)
        BigDecimal couponRate=new BigDecimal(0.8);
        for (Channel channelObj : channelList) {
            if(null==channelObj){
                continue;
            }
            ChannelUser channelUser=channelDao.selectChannelUserById(channelObj.getChannelUserId());
            if(null==channelUser){
                continue;
            }
            couponRate=channelUser.getCoupon();
            if(null==couponRate){
                couponRate=new BigDecimal(0.8);
            }

            String channel = channelObj.getChannel();
            Integer channelUserId=channelObj.getChannelUserId();
            statisticsRequest.setChannel(channel);
            dataStatisticsRequest.setChannel(channel);
            // 意向订单数
            Integer intentionOrderNum = platformStatisticsDao.getChannelOrderData(startTime, endTime, platform, channel, null, null, null);
            // 无地址数
            Integer noAddressOrderNum = platformStatisticsDao.getChannelOrderData(startTime, endTime, platform, channel,"1", null, null);
            // 支付订单数
            Integer payOrderNum = platformStatisticsDao.getChannelOrderData(startTime, endTime, platform, channel, null, 1, null);
            // 首单人数
            Integer firstBuyNum = platformStatisticsDao.getChannelOrderData(startTime, endTime, platform, channel,null, 1, 1);


            // 支付总金额
            BigDecimal payMoney = Optional.ofNullable(platformStatisticsDao.getPayMoney(statisticsRequest)).orElse(BigDecimal.ZERO);
            // 成本
            BigDecimal costMoney = Optional.ofNullable(platformStatisticsDao.getCostMoney(statisticsRequest)).orElse(BigDecimal.ZERO);
            // 利润
            BigDecimal profit = payMoney.subtract(costMoney);
            // 实际订单数
            Integer realOrderNum = intentionOrderNum - noAddressOrderNum;
            // uv
            Integer uv = this.getUv(statisticsRequest);
            log.debug("channel:{},uv:{}", channel, uv);
            if(uv==0||intentionOrderNum==0){
                continue;
            }
            // 订单率  实际订单数/uv
            BigDecimal orderRatio = uv == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(realOrderNum)
                    .divide(BigDecimal.valueOf(uv), 4, RoundingMode.HALF_UP);

            // 支付率 （支付订单/实际订单数）
            BigDecimal payRatio = realOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(payOrderNum)
                    .divide(BigDecimal.valueOf(realOrderNum), 4, RoundingMode.HALF_UP);
//            if(payRatio.compareTo(BigDecimal.ZERO)>0&&payRatio.compareTo(new BigDecimal(0.35))<0){//支付率小于35%,需要处理额外扣除实际订单数（调节支付率）
//                intentionOrderNum = new BigDecimal(intentionOrderNum).multiply(new BigDecimal(0.9)).intValue();//订单率低于6%同时调节uv(调节订单率)
//                realOrderNum = intentionOrderNum - noAddressOrderNum;
//                if(realOrderNum<=0){
//                    intentionOrderNum=noAddressOrderNum;
//                    payOrderNum=0;
//                    payMoney=BigDecimal.ZERO;
//                    costMoney=BigDecimal.ZERO;
//                    profit=BigDecimal.ZERO;
//                }
//            }
            // 客单率 支付金额/支付数
            BigDecimal customRatio = payOrderNum == 0 ? BigDecimal.ZERO : payMoney
                    .divide(BigDecimal.valueOf(payOrderNum), 4, RoundingMode.HALF_UP);
            //处理扣量
            // 意向订单数
            Integer intentionOrderNumCoupon = new BigDecimal(intentionOrderNum).multiply(couponRate).intValue();
            // 无地址数
            Integer noAddressOrderNumCoupon = noAddressOrderNum;

            // 支付订单数
            Integer payOrderNumCoupon = new BigDecimal(payOrderNum).multiply(couponRate).intValue();
            // 实际订单数
            Integer realOrderNumCoupon = (intentionOrderNumCoupon - noAddressOrderNumCoupon)>0?(intentionOrderNumCoupon - noAddressOrderNumCoupon):0;
            // 首单人数
            Integer firstBuyNumCoupon = new BigDecimal(firstBuyNum).multiply(couponRate).intValue();
            // 支付总金额
            BigDecimal payMoneyCoupon = payMoney.multiply(couponRate);
            // 利润
            BigDecimal profitCoupon = payMoney.subtract(costMoney).multiply(couponRate);
            // 成本
            BigDecimal costMoneyCoupon = payMoneyCoupon.subtract(profitCoupon);
            // uv
            Integer uvCoupon = new BigDecimal(uv).multiply(couponRate).intValue();
            // 订单率 实际订单数/uv
            BigDecimal orderRatioCoupon = uvCoupon == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(realOrderNumCoupon)
                    .divide(BigDecimal.valueOf(uvCoupon), 4, RoundingMode.HALF_UP);
            // 支付率 （支付订单/实际订单数）
            BigDecimal payRatioCoupon = realOrderNumCoupon == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(payOrderNumCoupon)
                    .divide(BigDecimal.valueOf(realOrderNumCoupon), 4, RoundingMode.HALF_UP);
            // 客单率 支付金额/支付数
            BigDecimal customRatioCoupon = payOrderNumCoupon == 0 ? BigDecimal.ZERO : payMoneyCoupon
                    .divide(BigDecimal.valueOf(payOrderNumCoupon), 4, RoundingMode.HALF_UP);


            // 激活用户
            Integer activeUser = platformStatisticsDao.getActiveUser(dataStatisticsRequest);
            // 新增用户
            Integer newAddUser = platformStatisticsDao.getNewAddUser(dataStatisticsRequest);
            // 点击地址数
            Integer clickAddressNum = platformStatisticsDao.getClickAddress(dataStatisticsRequest);
            ChannelStatisticsNew channelStatistics = new ChannelStatisticsNew();
            channelStatistics.setIntentionOrderNum(intentionOrderNum);
            channelStatistics.setNoAddressOrderNum(noAddressOrderNum);
            channelStatistics.setPayOrderNum(payOrderNum);
            channelStatistics.setDaus(uv);
            channelStatistics.setFirstBuyNum(firstBuyNum);
            channelStatistics.setProfit(profit);
            channelStatistics.setCostMoney(costMoney);
            channelStatistics.setRealOrderNum(realOrderNum);
            channelStatistics.setPayRatio(payRatio);
            channelStatistics.setPayMoney(payMoney);
            channelStatistics.setOrderRatio(orderRatio);
            channelStatistics.setCustomerRatio(customRatio);

            channelStatistics.setActiveUser(activeUser);
            channelStatistics.setAddressClickNum(clickAddressNum);
            channelStatistics.setNewUser(newAddUser);
            channelStatistics.setSource(platform);
            channelStatistics.setChannel(channel);
            try {
                channelStatistics.setRecordTime(sdf.parse(endTimeStr + " 23:59:59"));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Integer dataUserId=channelObj.getDataUserId();
            if(dataUserId!=null&&dataUserId>0){//有所属数据来源用户
                ChannelStatisticsNew  dataUserChannelStatisticsNew=new ChannelStatisticsNew();
                BeanUtils.copyProperties(channelStatistics,dataUserChannelStatisticsNew);
                dataUserChannelStatisticsNew.setChannelUid(dataUserId);
                saveDataUserStatistics(startTimeStr,endTimeStr,dataUserChannelStatisticsNew);
            }
            if(4==channelUserId){//ma
                ChannelStatisticsNew  parentUserChannelStatisticsNew=new ChannelStatisticsNew();
                BeanUtils.copyProperties(channelStatistics,parentUserChannelStatisticsNew);
                parentUserChannelStatisticsNew.setChannelUid(8);
                saveDataUserStatistics(startTimeStr,endTimeStr,parentUserChannelStatisticsNew);
            }else if(5==channelUserId){//gu
                ChannelStatisticsNew  parentUserChannelStatisticsNew=new ChannelStatisticsNew();
                BeanUtils.copyProperties(channelStatistics,parentUserChannelStatisticsNew);
                parentUserChannelStatisticsNew.setChannelUid(9);
                saveDataUserStatistics(startTimeStr,endTimeStr,parentUserChannelStatisticsNew);
            }else if(17==channelUserId){//中辉云hth
                ChannelStatisticsNew  parentUserChannelStatisticsNew=new ChannelStatisticsNew();
                BeanUtils.copyProperties(channelStatistics,parentUserChannelStatisticsNew);
                parentUserChannelStatisticsNew.setChannelUid(18);
                saveDataUserStatistics(startTimeStr,endTimeStr,parentUserChannelStatisticsNew);
            }
            ChannelStatisticsNew channelOrderData = new ChannelStatisticsNew();
            channelOrderData.setIntentionOrderNum(intentionOrderNumCoupon);
            channelOrderData.setNoAddressOrderNum(noAddressOrderNumCoupon);
            channelOrderData.setPayOrderNum(payOrderNumCoupon);
            channelOrderData.setDaus(uvCoupon);
            channelOrderData.setFirstBuyNum(firstBuyNumCoupon);
            channelOrderData.setProfit(profitCoupon);
            channelOrderData.setCostMoney(costMoneyCoupon);
            channelOrderData.setRealOrderNum(realOrderNumCoupon);
            channelOrderData.setPayRatio(payRatioCoupon);
            channelOrderData.setPayMoney(payMoneyCoupon);
            channelOrderData.setOrderRatio(orderRatioCoupon);
            channelOrderData.setCustomerRatio(customRatioCoupon);

            channelOrderData.setActiveUser(activeUser);
            channelOrderData.setAddressClickNum(clickAddressNum);
            channelOrderData.setNewUser(newAddUser);
            channelOrderData.setSource(platform);
            channelOrderData.setChannel(channel);
            channelOrderData.setChannelUid(channelUserId);
            try {
                channelOrderData.setRecordTime(sdf.parse(endTimeStr + " 23:59:59"));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            ChannelStatisticsNew oldChannelStatisticsNew=channelStatisticsNewDao.selectStatistics(channelUserId,channelObj.getChannel(), startTimeStr + " 00:00:00", endTimeStr + " 23:59:59");
            if(null!=oldChannelStatisticsNew){//处理扣量
                if(uvCoupon>oldChannelStatisticsNew.getDaus()&&intentionOrderNumCoupon>oldChannelStatisticsNew.getIntentionOrderNum()
                    &&payOrderNumCoupon>oldChannelStatisticsNew.getPayOrderNum()&&payMoneyCoupon.compareTo(oldChannelStatisticsNew.getPayMoney())>0
                    &&costMoneyCoupon.compareTo(oldChannelStatisticsNew.getCostMoney())>0){
                    channelStatisticsNewDao.deleteByCurDay(channelUserId,channel, startTimeStr + " 00:00:00", endTimeStr + " 23:59:59");//删除
                    channelStatisticsNewDao.insert(channelOrderData);
                }
            }else{
                channelStatisticsNewDao.insert(channelOrderData);
            }
            //需要拷贝渠道统计数据到bht
            if(copyDataToBhtChannelList.contains(channel)){
                saveBhtChannelData(channel,startTimeStr,endTimeStr,channelOrderData);
            }
        }
    }
    private void saveBhtChannelData(String channel,String startTimeStr,String endTimeStr,ChannelStatisticsNew channelOrderData){
        int channelUserId=14;
        channelOrderData.setChannelUid(channelUserId);
        ChannelStatisticsNew oldChannelStatisticsNew=channelStatisticsNewDao.selectStatistics(channelUserId,channel, startTimeStr + " 00:00:00", endTimeStr + " 23:59:59");
        if(null!=oldChannelStatisticsNew){//处理扣量
            if(channelOrderData.getDaus()>oldChannelStatisticsNew.getDaus()&&channelOrderData.getIntentionOrderNum()>oldChannelStatisticsNew.getIntentionOrderNum()
                    &&channelOrderData.getPayOrderNum()>oldChannelStatisticsNew.getPayOrderNum()&&channelOrderData.getPayMoney().compareTo(oldChannelStatisticsNew.getPayMoney())>0
                    &&channelOrderData.getCostMoney().compareTo(oldChannelStatisticsNew.getCostMoney())>0){
                channelStatisticsNewDao.deleteByCurDay(channelUserId,channel, startTimeStr + " 00:00:00", endTimeStr + " 23:59:59");//删除
                channelStatisticsNewDao.insert(channelOrderData);
            }
        }else{
            channelStatisticsNewDao.insert(channelOrderData);
        }
    }
    /**
     * 临时补历史数据使用
     * @param startTime
     * @param endTime
     * @param platform
     * @param channelUid
     * @param statisticsRequest
     */
    public void getChannelDataTempByChannelUid(LocalDateTime startTime, LocalDateTime endTime, String platform, Integer channelUid, DataStatisticsRequest statisticsRequest,BigDecimal coupon,BigDecimal parentCoupon,BigDecimal dataCoupon,Integer type,Integer dayInterval) {
        List<Channel> channelList = new ArrayList<>();
        List<Channel> allchannels = channelDao.getChannelNameList(dayInterval);

        if(allchannels != null && !allchannels.isEmpty()) {
            for(Channel channel:allchannels) {
                if (channelUid.equals(channel.getChannelUserId())){
                    channelList.add(channel);
                }
            }
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startTimeStr = "";
        String endTimeStr = "";
        if (null != startTime) {
            startTimeStr = df.format(startTime);
        }
        if (null != endTime) {
            endTimeStr = df.format(endTime);
            statisticsRequest.setSearchDate(endTimeStr);
        }
        for (Channel channelObj : channelList) {
            if (null == channelObj) {
                continue;
            }
            String channel = channelObj.getChannel();
            Integer channelUserId = channelObj.getChannelUserId();
            statisticsRequest.setChannel(channel);

            // 意向订单数
            Integer intentionOrderNum = platformStatisticsDao.getChannelOrderData(startTime, endTime, platform, channel, null, null, null);
            // 无地址数
            Integer noAddressOrderNum = platformStatisticsDao.getChannelOrderData(startTime, endTime, platform, channel, "1", null, null);
            // 支付订单数
            Integer payOrderNum = platformStatisticsDao.getChannelOrderData(startTime, endTime, platform, channel, null, 1, null);
            // 首单人数
            Integer firstBuyNum = platformStatisticsDao.getChannelOrderData(startTime, endTime, platform, channel, null, 1, 1);


            // 支付总金额
            BigDecimal payMoney = Optional.ofNullable(platformStatisticsDao.getPayMoney(statisticsRequest)).orElse(BigDecimal.ZERO);
            // 成本
            BigDecimal costMoney = Optional.ofNullable(platformStatisticsDao.getCostMoney(statisticsRequest)).orElse(BigDecimal.ZERO);
            // 利润
            BigDecimal profit = payMoney.subtract(costMoney);
            // 实际订单数
            Integer realOrderNum = intentionOrderNum - noAddressOrderNum;
            // uv
            Integer uv = this.getUv(statisticsRequest);
            log.debug("channel:{},uv:{}", channel, uv);
            if (uv == 0 || intentionOrderNum == 0) {
                continue;
            }
            // 订单率 实际订单数/uv
            BigDecimal orderRatio = uv == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(realOrderNum)
                    .divide(BigDecimal.valueOf(uv), 4, RoundingMode.HALF_UP);
            // 支付率 （支付订单/实际订单数）
            BigDecimal payRatio = realOrderNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(payOrderNum)
                    .divide(BigDecimal.valueOf(realOrderNum), 4, RoundingMode.HALF_UP);
            // 客单率 支付金额/支付数
            BigDecimal customRatio = payOrderNum == 0 ? BigDecimal.ZERO : payMoney
                    .divide(BigDecimal.valueOf(payOrderNum), 4, RoundingMode.HALF_UP);

            // 激活用户
            Integer activeUser = platformStatisticsDao.getActiveUser(statisticsRequest);
            // 新增用户
            Integer newAddUser = platformStatisticsDao.getNewAddUser(statisticsRequest);
            // 点击地址数
            Integer clickAddressNum = platformStatisticsDao.getClickAddress(statisticsRequest);

            ChannelStatisticsNew channelStatistics = new ChannelStatisticsNew();
            channelStatistics.setIntentionOrderNum(intentionOrderNum);
            channelStatistics.setNoAddressOrderNum(noAddressOrderNum);
            channelStatistics.setPayOrderNum(payOrderNum);
            channelStatistics.setDaus(uv);
            channelStatistics.setFirstBuyNum(firstBuyNum);
            channelStatistics.setProfit(profit);
            channelStatistics.setCostMoney(costMoney);
            channelStatistics.setRealOrderNum(realOrderNum);
            channelStatistics.setPayRatio(payRatio);
            channelStatistics.setPayMoney(payMoney);
            channelStatistics.setOrderRatio(orderRatio);
            channelStatistics.setCustomerRatio(customRatio);

            channelStatistics.setActiveUser(activeUser);
            channelStatistics.setAddressClickNum(clickAddressNum);
            channelStatistics.setNewUser(newAddUser);
            channelStatistics.setSource(platform);
            channelStatistics.setChannel(channel);
            channelStatistics.setChannelUid(channelUid);
            try {
                channelStatistics.setRecordTime(sdf.parse(endTimeStr + " 23:59:59"));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            if(3==type) {
                Integer dataUserId = channelObj.getDataUserId();
                if (dataUserId != null && dataUserId > 0) {//有所属数据来源用户
                    ChannelStatisticsNew dataUserChannelStatisticsNew = new ChannelStatisticsNew();
                    BeanUtils.copyProperties(channelStatistics, dataUserChannelStatisticsNew);
                    dataUserChannelStatisticsNew.setChannelUid(dataUserId);
                    saveDataUserStatistics(startTimeStr, endTimeStr,dataCoupon,dataUserChannelStatisticsNew);
                }
            }
            if(2==type) {
                if (4 == channelUserId) {//ma
                    ChannelStatisticsNew parentUserChannelStatisticsNew = new ChannelStatisticsNew();
                    BeanUtils.copyProperties(channelStatistics, parentUserChannelStatisticsNew);
                    parentUserChannelStatisticsNew.setChannelUid(8);
                    saveDataUserStatistics(startTimeStr, endTimeStr,parentCoupon, parentUserChannelStatisticsNew);
                } else if (5 == channelUserId) {//gu
                    ChannelStatisticsNew parentUserChannelStatisticsNew = new ChannelStatisticsNew();
                    BeanUtils.copyProperties(channelStatistics, parentUserChannelStatisticsNew);
                    parentUserChannelStatisticsNew.setChannelUid(9);
                    saveDataUserStatistics(startTimeStr, endTimeStr,parentCoupon, parentUserChannelStatisticsNew);
                }
            }
            saveDataUserStatistics(startTimeStr,endTimeStr,coupon,channelStatistics);
        }
    }

    private void saveDataUserStatistics(String startTimeStr,String endTimeStr,BigDecimal couponRate,ChannelStatisticsNew channelStatistics){
        log.debug("saveDataUserStatistics,uid={},coupon={}",channelStatistics.getChannelUid(),couponRate);
        ChannelStatisticsNew oldChannelStatisticsNew=channelStatisticsNewDao.selectStatistics(channelStatistics.getChannelUid(),channelStatistics.getChannel(), startTimeStr + " 00:00:00", endTimeStr + " 23:59:59");
        //处理扣量
        // 意向订单数
        Integer intentionOrderNumCoupon = new BigDecimal(channelStatistics.getIntentionOrderNum()).multiply(couponRate).intValue();
        // 无地址数
        Integer noAddressOrderNumCoupon = channelStatistics.getNoAddressOrderNum();
        // 支付订单数
        Integer payOrderNumCoupon = new BigDecimal(channelStatistics.getPayOrderNum()).multiply(couponRate).intValue();
        // 实际订单数
        Integer realOrderNumCoupon = (intentionOrderNumCoupon - noAddressOrderNumCoupon)>0?(intentionOrderNumCoupon - noAddressOrderNumCoupon):0;
        // 首单人数
        Integer firstBuyNumCoupon = new BigDecimal(channelStatistics.getFirstBuyNum()).multiply(couponRate).intValue();
        // 支付总金额
        BigDecimal payMoneyCoupon = channelStatistics.getPayMoney().multiply(couponRate);
        // 利润
        BigDecimal profitCoupon = channelStatistics.getPayMoney().subtract(channelStatistics.getCostMoney()).multiply(couponRate);
        // 成本
        BigDecimal costMoneyCoupon = payMoneyCoupon.subtract(profitCoupon);
        // uv
        Integer uvCoupon = new BigDecimal(channelStatistics.getDaus()).multiply(couponRate).intValue();
        // 订单率 实际订单数/uv
        BigDecimal orderRatioCoupon = uvCoupon == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(realOrderNumCoupon)
                .divide(BigDecimal.valueOf(uvCoupon), 4, RoundingMode.HALF_UP);
        // 支付率 （支付订单/实际订单数）
        BigDecimal payRatioCoupon = realOrderNumCoupon == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(payOrderNumCoupon)
                .divide(BigDecimal.valueOf(realOrderNumCoupon), 4, RoundingMode.HALF_UP);
        // 客单率 支付金额/支付数
        BigDecimal customRatioCoupon = payOrderNumCoupon == 0 ? BigDecimal.ZERO : payMoneyCoupon
                .divide(BigDecimal.valueOf(payOrderNumCoupon), 4, RoundingMode.HALF_UP);

        channelStatistics.setIntentionOrderNum(intentionOrderNumCoupon);
        channelStatistics.setNoAddressOrderNum(noAddressOrderNumCoupon);
        channelStatistics.setPayOrderNum(payOrderNumCoupon);
        channelStatistics.setDaus(uvCoupon);
        channelStatistics.setFirstBuyNum(firstBuyNumCoupon);
        channelStatistics.setProfit(profitCoupon);
        channelStatistics.setCostMoney(costMoneyCoupon);
        channelStatistics.setRealOrderNum(realOrderNumCoupon);
        channelStatistics.setPayRatio(payRatioCoupon);
        channelStatistics.setPayMoney(payMoneyCoupon);
        channelStatistics.setOrderRatio(orderRatioCoupon);
        channelStatistics.setCustomerRatio(customRatioCoupon);
        if(null!=oldChannelStatisticsNew){//处理扣量
            if(uvCoupon>oldChannelStatisticsNew.getDaus()&&intentionOrderNumCoupon>oldChannelStatisticsNew.getIntentionOrderNum()
                    &&payOrderNumCoupon>oldChannelStatisticsNew.getPayOrderNum()&&payMoneyCoupon.compareTo(oldChannelStatisticsNew.getPayMoney())>0
                    &&costMoneyCoupon.compareTo(oldChannelStatisticsNew.getCostMoney())>0){
                channelStatisticsNewDao.deleteByCurDay(oldChannelStatisticsNew.getChannelUid(),oldChannelStatisticsNew.getChannel(), startTimeStr + " 00:00:00", endTimeStr + " 23:59:59");//删除
                channelStatisticsNewDao.insert(channelStatistics);
            }
        }else{
            channelStatisticsNewDao.insert(channelStatistics);
        }
    }
    /**
     * 保存渠道数据来源用户统计报表
     * @param channelStatistics
     */
    private void saveDataUserStatistics(String startTimeStr,String endTimeStr,ChannelStatisticsNew channelStatistics){
        ChannelUser channelUser=channelDao.selectChannelUserById(channelStatistics.getChannelUid());
        if(null==channelUser){
            return;
        }
        //扣量(给的比例)
        BigDecimal couponRate=channelUser.getCoupon();
        if(couponRate==null){
            couponRate=new BigDecimal(0.85);
        }

        saveDataUserStatistics(startTimeStr,endTimeStr,couponRate,channelStatistics);
    }

    /**
     * 获取uv
     *
     * @return
     */
    public Integer getUv(DataStatisticsRequest dataStatisticsRequest) {
        log.info("===dataStatisticsRequest={}", dataStatisticsRequest);
        Criteria criteria = this.commonCriteria(dataStatisticsRequest);
        DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String startDate=sdf.format(dataStatisticsRequest.getStartTime());
        String endDate=sdf.format(dataStatisticsRequest.getEndTime());
        if(startDate.equals(endDate)){//统计起止时间为同一天，直接查询日集合
            return Optional.ofNullable(this.aggregateByUuid(criteria, "page:" +startDate).size()).orElse(0);
        }else {
            return Optional.ofNullable(this.aggregateByUuid(criteria).size()).orElse(0);
        }
    }

    /**
     * 通用查询
     *
     * @param dataStatisticsRequest
     * @return
     */
    public Criteria commonCriteria(DataStatisticsRequest dataStatisticsRequest) {
        Criteria criteria = Criteria.where("dayTime").is(dataStatisticsRequest.getSearchDate());
        if (StringUtils.isNotEmpty(dataStatisticsRequest.getPlatform())) {
            criteria.and("platform").is(dataStatisticsRequest.getPlatform());
        }
        if (StringUtils.isNotEmpty(dataStatisticsRequest.getChannel())) {
            criteria.and("channel").is(dataStatisticsRequest.getChannel());
        }
        return criteria;
    }

    public List<Map> aggregateByUuid(Criteria criteria) {
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("uuid").count().as("count").last("uuid").as("uuid")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, PAGE_STATISTICS, Map.class);
        return results.getMappedResults();
    }

    public List<Map> aggregateByUuid(Criteria criteria, String collectionName) {
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("uuid").count().as("count").last("uuid").as("uuid")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, collectionName, Map.class);
        return results.getMappedResults();
    }

    /**
     * 查询时间格式化
     *
     * @param dataStatisticsRequest
     * @return
     */
    public DataStatisticsRequest getSearchDate(DataStatisticsRequest dataStatisticsRequest) {

        String searchDate = dataStatisticsRequest.getSearchDate();
        if (Strings.isNotEmpty(searchDate)) {
            LocalDate day = LocalDate.parse(searchDate);
            LocalDate toDay = LocalDate.parse(searchDate).plusDays(1L);
            LocalDateTime startTime = day.atStartOfDay();
            LocalDateTime endTime = toDay.atStartOfDay();
            dataStatisticsRequest.setStartTime(startTime);
            dataStatisticsRequest.setEndTime(endTime);
            return dataStatisticsRequest;
        }
        return dataStatisticsRequest;
    }
}
